<?php

class LoginController extends AppController {

    public $uses = array();
    public $components = array('Session');
    private $endpoints = array(
        'Facebook' => array(
            '_oauth_endpoint' => 'https://www.facebook.com/dialog/oauth',
            '_token_endpoint' => 'https://graph.facebook.com/oauth/access_token',
            '_oauth_scope' => 'email',
            'client_id' => 'client_id',
            'client_secret' => 'client_secret',
            'redirect_uri' => 'redirect_uri',
            'scope' => 'scope',
            'state' => 'state',
            'code' => 'code',
            'response_type' => 'response_type'
        ),
        'Google' => array(
            '_oauth_endpoint' => 'https://accounts.google.com/o/oauth2/auth',
            '_token_endpoint' => 'https://accounts.google.com/o/oauth2/token',
            '_oauth_scope' => 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email',
            'client_id' => 'client_id',
            'client_secret' => 'client_secret',
            'redirect_uri' => 'redirect_uri',
            'scope' => 'scope',
            'state' => 'state',
            'code' => 'code',
            'response_type' => 'response_type'
        )
    );

    public function login($type = NULL) {
        if ($type == NULL)
            return;
        if (!array_key_exists($type, $this->endpoints))
            return;

        $endpoint = $this->endpoints[$type];

        $this->set('title_for_layout', 'Logowanie przez ' . $type);

        $code = isset($this->request->query[$endpoint['code']]) ? $this->request->query[$endpoint['code']] : null;

        //first run -> redirect to external login dialog
        if (empty($code)) {
            $this->Session->delete('ExtAuth');
            $state = md5(uniqid(rand(), TRUE));
            $this->Session->write('ExtAuth.state', $state); //CSRF protection
            $dialog_query = http_build_query(array(
                $endpoint['client_id'] => Configure::read($type . ".appId"),
                $endpoint['scope'] => $endpoint['_oauth_scope'],
                $endpoint['redirect_uri'] => Router::url(array('plugin' => 'ExtAuth', 'controller' => 'login', 'action' => 'login', $type), true),
                $endpoint['response_type'] => 'code',
                $endpoint['state'] => $state
                    ));
            $dialog_url = $endpoint['_oauth_endpoint'] . "?" . $dialog_query;
            echo("<script> top.location.href='" . $dialog_url . "'</script>");
            die();
        }
        $userinfo_object = null;

        //we have the code, now to get the access token...
        if ($this->request->query[$endpoint['state']] == $this->Session->read('ExtAuth.state')) {
            $params = array(
                $endpoint['client_id'] => Configure::read($type . ".appId"),
                $endpoint['client_secret'] => Configure::read($type . ".appSecret"),
                $endpoint['redirect_uri'] => Router::url(array('plugin' => 'ExtAuth', 'controller' => 'login', 'action' => 'login', $type), true),
                $endpoint['code'] => $code,
                "grant_type" => "authorization_code"
            );
            $params = http_build_query($params);

            if ($type == "Google") {
                //MUST use POST instead of GET and data returned as JSON
                $curl = curl_init($endpoint['_token_endpoint']);
                curl_setopt($curl, CURLOPT_POST, true);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                $page = curl_exec($curl);
                curl_close($curl);

                $access_token_object = json_decode($page, TRUE);
                $access_token = $access_token_object['access_token'];
                $userinfo = file_get_contents("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" . $access_token);
                $userinfo_object = json_decode($userinfo, TRUE);
            } else if ($type == "Facebook") {
                //data returned as XXXX=yyyyy&aaaaa=BBBBB
                $page = file_get_contents($endpoint['_token_endpoint'] . "?" . $params);
                $access_token_object = array();
                parse_str($page, $access_token_object);
                $access_token = $access_token_object['access_token'];
                $userinfo = file_get_contents("https://graph.facebook.com/me?access_token=" . $access_token);
                $userinfo_object = json_decode($userinfo, TRUE);
            }
        } else {
            echo("The state does not match. Aborting.");
        }
        //END OAUTH 2.0

        if ($userinfo_object) {
            $extAuthData = array(
                'email' => $userinfo_object['email'],
                'ext_id' => $userinfo_object['id'],
                'name' => $userinfo_object['name'],
                'type' => $type,
                'link'  => $userinfo_object['link'],
            );
            $this->Session->write('ExtAuth', $extAuthData);
            $this->redirect(array('plugin' => NULL, 'controller' => 'users', 'action' => 'login', 'extauth'));
        }
    }

}

